package com.arcsoft.api.system.face;

import com.arcsoft.api.system.dto.FaceAttributesResponse;
import com.arcsoft.face.*;
import com.arcsoft.face.enums.*;
import com.arcsoft.face.toolkit.ImageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
public class FaceManager {
    String appId = "";
    String sdkKey = "";
    String activeKey = "";
    private CustomFaceEnginePool facePool;
    public FaceManager() {
    }
    public void init() {
        try {
            //引擎配置
            EngineConfiguration engineConfiguration = new EngineConfiguration();
            EngineConfiguration coreEngineConfiguration = new EngineConfiguration();

            //设置检测模式为image
            engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
            coreEngineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
            //设置人脸角度为全角度
            engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
            coreEngineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
            //设置可检测最大人脸数
            engineConfiguration.setDetectFaceMaxNum(1);
            coreEngineConfiguration.setDetectFaceMaxNum(1);
            //设置人脸识别的模型，ASF_REC_MIDDLE：中等模型，ASF_REC_LARGE：大模型
            engineConfiguration.setFaceModel(FaceModel.ASF_REC_MIDDLE);
            coreEngineConfiguration.setFaceModel(FaceModel.ASF_REC_MIDDLE);
            //功能配置
            FunctionConfiguration functionConfiguration = new FunctionConfiguration();
            //年龄检测
            functionConfiguration.setSupportAge(true);
            //人脸检测
            functionConfiguration.setSupportFaceDetect(true);
            //人脸识别
            functionConfiguration.setSupportFaceRecognition(true);
            //性别检测
            functionConfiguration.setSupportGender(true);
            //活体检测
            functionConfiguration.setSupportLiveness(true);
            //ir活体检测
            functionConfiguration.setSupportIRLiveness(true);
            //图像质量检测
            functionConfiguration.setSupportImageQuality(true);
            //口罩检测
            functionConfiguration.setSupportMaskDetect(true);
            engineConfiguration.setFunctionConfiguration(functionConfiguration);

            GenericObjectPoolConfig<AFaceEngine> config = new GenericObjectPoolConfig<>();
            config.setMaxTotal(5);
            facePool = new CustomFaceEnginePool(new FaceEngineFactory(engineConfiguration,coreEngineConfiguration,appId,sdkKey,activeKey), config);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void loadAllFace(List<FaceFeatureInfo> faceFeatureInfoList) throws Exception {
        AFaceEngine faceEngine = facePool.borrowCoreObject(5000);
        int i = faceEngine.registerFaceFeature(faceFeatureInfoList);
        log.info("load all face  count：{}", +faceFeatureInfoList.size());
        log.info("load all face  res：{}", +i);
        facePool.returnObject(faceEngine);
    }

    //人脸检测
    public ArrayList<FaceInfo> detectFaces(ImageInfo imageInfo) throws Exception {
        ArrayList<FaceInfo> faceInfos = new ArrayList<>();
        AFaceEngine faceEngine = facePool.borrowObject();
        int detectFacesCode = faceEngine.detectFaces(imageInfo, faceInfos);
        log.info("人脸属性检测 res:{}", detectFacesCode);
        facePool.returnObject(faceEngine);
        return faceInfos;
    }

    //图像质量检测
    public float imageQuality(ImageInfo imageInfo, FaceInfo faceInfo) throws Exception {
        ImageQuality imageQuality = new ImageQuality();
        AFaceEngine faceEngine = facePool.borrowObject();
        int imageQualityCode =faceEngine.imageQualityDetect(imageInfo, faceInfo, 0, imageQuality);
        facePool.returnObject(faceEngine);
        log.info("图像质量检测 res:{}", imageQualityCode);
        log.info("图像质量检测分数:{}", imageQuality.getFaceQuality());
        return imageQuality.getFaceQuality();
    }

    public FaceAttributesResponse faceAttributes(ImageInfo imageInfo, FaceInfo faceInfo) throws Exception {
        FaceAttributesResponse faceAttributesResponse = new FaceAttributesResponse();
        FunctionConfiguration configuration = new FunctionConfiguration();
        configuration.setSupportAge(true);
        configuration.setSupportGender(true);
        configuration.setSupportLiveness(true);
        configuration.setSupportMaskDetect(true);
        ArrayList<FaceInfo> faceInfos = new ArrayList<>();
        faceInfos.add(faceInfo);
        AFaceEngine faceEngine = facePool.borrowObject();
        int faceAttributesCode = faceEngine.process(imageInfo, faceInfos, configuration);
        log.info("图像属性处理errorCode:{}", faceAttributesCode);
        //性别检测
        List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
        int genderCode = faceEngine.getGender(genderInfoList);
        log.info("性别 res：{}", +genderCode);
        log.info("性别：{}", +genderInfoList.get(0).getGender());
        faceAttributesResponse.setSex(genderInfoList.get(0).getGender() == 0?"男":"女");
        //年龄检测
        List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
        int ageCode = faceEngine.getAge(ageInfoList);
        log.info("年龄 res：{}", +ageCode);
        log.info("年龄：{}", ageInfoList.get(0).getAge());
        faceAttributesResponse.setAge(String.valueOf(ageInfoList.get(0).getAge()));
        //rgb活体检测
        List<LivenessInfo> livenessInfoList = new ArrayList<LivenessInfo>();
        int livenCode = faceEngine.getLiveness(livenessInfoList);
        log.info("RGB活体 res：{}", +livenCode);
        log.info("活体：{}", livenessInfoList.get(0).getLiveness());
        faceAttributesResponse.setLive(livenessInfoList.get(0).getLiveness()==0?"非真人":"真人");
        //口罩检测
        List<MaskInfo> maskInfoList = new ArrayList<MaskInfo>();
        int maskCode = faceEngine.getMask(maskInfoList);
        log.info("口罩 res：{}", +maskCode);
        log.info("口罩：{}", +maskInfoList.get(0).getMask());
        faceAttributesResponse.setMask(maskInfoList.get(0).getMask()==0?"无口罩":"有口罩");
        facePool.returnObject(faceEngine);
        return faceAttributesResponse;
    }

    public int irLivingDetect(ImageInfo irImg) throws Exception {
        AFaceEngine faceEngine = facePool.borrowObject();
        //IR属性处理
        List<FaceInfo> faceInfoListGray = new ArrayList<FaceInfo>();
        int irFaceDetectCode = faceEngine.detectFaces(irImg, faceInfoListGray);
        log.info("ir图像人脸检测 res：{}", +irFaceDetectCode);
        FunctionConfiguration configuration2 = new FunctionConfiguration();
        configuration2.setSupportIRLiveness(true);
        int irLivingCode = faceEngine.processIr(irImg, faceInfoListGray, configuration2);
        log.info("ir活体检测 res：{}", +irLivingCode);
        //IR活体检测
        List<IrLivenessInfo> irLivenessInfo = new ArrayList<>();
        int errorCode = faceEngine.getLivenessIr(irLivenessInfo);
        log.info("获取ir活体检测 res：{}", +errorCode);
        facePool.returnObject(faceEngine);
        return irLivenessInfo.get(0).getLiveness();
    }

    public int registerFace(FaceFeatureInfo faceFeatureInfo) throws Exception {
        AFaceEngine faceEngine = facePool.borrowCoreObject(5000);
        int i = faceEngine.registerFaceFeature(faceFeatureInfo);
        facePool.returnObject(faceEngine);
        return i;
    }

    public int removeFace(int searchId) throws Exception {
        AFaceEngine faceEngine = facePool.borrowCoreObject(5000);
        int i = faceEngine.removeFaceFeature(searchId);
        facePool.returnObject(faceEngine);
        return i;
    }

    public int updateFace(FaceFeatureInfo faceFeatureInfo) throws Exception {
        AFaceEngine faceEngine = facePool.borrowCoreObject(5000);
        int i = faceEngine.updateFaceFeature(faceFeatureInfo);
        facePool.returnObject(faceEngine);
        return i;
    }

    public SearchResult searchFace(FaceFeature faceFeature) throws Exception {
        AFaceEngine faceEngine = facePool.borrowCoreObject(5000);
        FaceSearchCount faceSearchCount = new FaceSearchCount();
        faceEngine.getFaceCount(faceSearchCount);
        log.info("引擎库face count：{}", +faceSearchCount.getCount());
        SearchResult searchResult = new SearchResult();
        int searchCode = faceEngine.searchFaceFeature(faceFeature, CompareModel.LIFE_PHOTO, searchResult);
        log.info("人脸搜索 res：{}", +searchCode);
        log.info("人脸搜索 sim：{}", +searchResult.getMaxSimilar());
        facePool.returnObject(faceEngine);
        return searchResult;
    }

    public FaceFeature extractFaceFeature(ImageInfo imageInfo, FaceInfo faceInfo, ExtractType type) throws Exception {
        AFaceEngine faceEngine = facePool.borrowObject();
        FaceFeature faceFeature = new FaceFeature();
        int extractCode = faceEngine.extractFaceFeature(imageInfo, faceInfo, type, 0, faceFeature);
        log.info("特征提取 res:{}", extractCode);
        facePool.returnObject(faceEngine);
        return faceFeature;
    }
}
